﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;

namespace Elite
{
    class ProcessAffinity
    {

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int GetCurrentThreadId();
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool GetProcessAffinityMask(IntPtr currentProcess, ref Int64 lpProcessAffinityMask, ref Int64 lpSystemAffinityMask);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int GetCurrentProcessorNumber();

        public static void Main1()
        {
            Int64 lpProcessAffinityMask = 0, lpSystemAffinityMask = 0;
            int i = 0, j = 0;
            Int64 procCount = Environment.ProcessorCount;
            Thread[] t = new Thread[procCount];

            IntPtr currentProcess = Process.GetCurrentProcess().Handle;
            Int64 currProcMask;

            GetProcessAffinityMask(currentProcess, ref lpProcessAffinityMask, ref lpSystemAffinityMask);

            Console.WriteLine("ProcessAffintityMask = {0}, SystemAffinityMask ={1}", lpProcessAffinityMask, lpSystemAffinityMask);

            for (i = 0; i < procCount; i++)
            {
                currProcMask = lpSystemAffinityMask & (1 << i);
                if (currProcMask >= 1)
                {
                    t[j] = new Thread(new ParameterizedThreadStart(DoWork));
                    object[] parameters = new object[] { currProcMask };
                    t[j++].Start(parameters);
                }
            }
            for (i = 0; i < j; i++)
            {
                t[i].Join();
            }
        }

        static void DoWork(object parameters)
        {

            object[] parameterArray = (object[])parameters;
            Int64 currProcMask = (Int64)parameterArray[0];

            foreach (ProcessThread pt in Process.GetCurrentProcess().Threads)
            {
                int utid = GetCurrentThreadId();
                if (utid == pt.Id)
                {
                    pt.ProcessorAffinity = (IntPtr)(currProcMask); // Set affinity for this thread to CPU #1

                    Thread.BeginThreadAffinity();
                    for (int i = 0; i < 100000; i++)
                    {
                        Console.WriteLine(i);
                    }
                    Thread.EndThreadAffinity();

                    Console.WriteLine("Running on processor {0}", GetCurrentProcessorNumber());
                    Console.ReadKey();
                }
            }

        }
    }
}
